package com.hycreate.platform.common.sdk.tts.tts;

import java.io.FileInputStream;
import java.io.FileOutputStream;

//import com.hycreate.platform.common.sdk.tts.sys.AccountInfo;
import com.hycreate.platform.common.sdk.tts.sys.HciCloudSysHelper;
import com.sinovoice.hcicloudsdk.common.HciErrorCode;

/**
 * @author sinovoice
 */
public class HciCloudTtsMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		execute("d:/hy_surface", "d:/synth.wav", "今年小王八岁了。");
	}

	/**
	 * 文字信息转换
	 * 
	 * @param sPath
	 *            项目根目录
	 * @param filePath
	 *            音频输出目录
	 * @param context
	 *            音频内容
	 */
	public static void execute(String sPath, String filePath, String context) {
		/**
		 * 加载用户信息工具类
		 */
		// AccountInfo mAccountInfo;

		/**
		 * HciCloud帮助类，可完成灵云系统初始化，释放操作。
		 */
		HciCloudSysHelper mHciCloudSysHelper;

		/**
		 * TTS帮助类， 可完成TTS能力的初始化，开始合成，释放操作。
		 */
		HciCloudTtsHelper mHciCloudTtsHelper;

		// mAccountInfo = AccountInfo.getInstance();
		// boolean loadResult = mAccountInfo.loadAccountInfo();
		// if (loadResult) {
		// // 加载信息成功进入主界面
		// System.out.println("加载灵云账号成功");
		// } else {
		// // 加载信息失败，显示失败界面
		// System.out.println("加载灵云账号失败！请在assets/AccountInfo.txt文件中填写正确的灵云账户信息，账户需要从www.hcicloud.com开发者社区上注册申请。");
		// return;
		// }

		mHciCloudSysHelper = HciCloudSysHelper.getInstance(sPath);
		mHciCloudTtsHelper = HciCloudTtsHelper.getInstance(sPath, filePath);

		// 此方法是线程阻塞的，当且仅当有结果返回才会继续向下执行。
		// 此处只是演示合成能力用法，没有对耗时操作进行处理。需要开发者放入后台线程进行初始化操作
		// 必须首先调用HciCloudSys的初始化方法
		int sysInitResult = mHciCloudSysHelper.init();
		if (sysInitResult != HciErrorCode.HCI_ERR_NONE) {
			System.out.println("hci init error, error code = " + sysInitResult);
			return;
		} else {
			System.out.println("hci init success");
		}

		// 此方法是线程阻塞的，当且仅当有结果返回才会继续向下执行。
		// 此处只是演示合成能力用法，没有对耗时操作进行处理。需要开发者放入后台线程进行初始化操作
		// 只有HciCloudSys初始化成功后，才能调用asr的初始化方法
		int ttsInitResult = mHciCloudTtsHelper.init();
		if (ttsInitResult != HciErrorCode.HCI_ERR_NONE) {
			System.out.println("tts init error " + ttsInitResult);
			return;
		} else {
			System.out.println("tts init success");
		}

		mHciCloudTtsHelper.synth(context);

		// -------------反初始化------------------------------------------
		// 终止TTs能力
		int ttsReleaseResult = mHciCloudTtsHelper.release();
		if (ttsReleaseResult != HciErrorCode.HCI_ERR_NONE) {
			System.out.println("hciTtsRelease failed:" + ttsReleaseResult);
			mHciCloudSysHelper.release();
			return;
		} else {
			System.out.println("hciTtsRelease success");
		}

		// 终止 灵云 系统
		int sysReleaseRet = mHciCloudSysHelper.release();
		if (HciErrorCode.HCI_ERR_NONE != sysReleaseRet) {
			System.out.println("hciRelease failed:" + sysReleaseRet);
		}
		System.out.println("hciRelease Success");

		try {
			convertAudioFiles(filePath, filePath.replace("pcm", "wav"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 音频格式转换
	 * 
	 * @param src
	 *            源文件
	 * @param target
	 *            目标文件
	 * @throws Exception
	 */
	private static void convertAudioFiles(String src, String target) throws Exception {
		FileInputStream fis = new FileInputStream(src);
		FileOutputStream fos = new FileOutputStream(target);

		// 璁＄畻闀垮害
		byte[] buf = new byte[1024 * 4];
		int size = fis.read(buf);
		int PCMSize = 0;
		while (size != -1) {
			PCMSize += size;
			size = fis.read(buf);
		}
		fis.close();

		// 濉叆鍙傛暟锛屾瘮鐗圭巼绛夌瓑銆傝繖閲岀敤鐨勬槸16浣嶅崟澹伴亾 8000 hz
		WaveHeader header = new WaveHeader();
		// 闀垮害瀛楁 = 鍐呭鐨勫ぇ灏忥紙PCMSize) +
		// 澶撮儴瀛楁鐨勫ぇ灏�涓嶅寘鎷墠闈�瀛楄妭鐨勬爣璇嗙RIFF浠ュ強fileLength鏈韩鐨�瀛楄妭)
		header.fileLength = PCMSize + (44 - 8);
		header.FmtHdrLeth = 16;
		header.BitsPerSample = 16;
		header.Channels = 1;
		header.FormatTag = 0x0001;
		header.SamplesPerSec = 14000;
		header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
		header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
		header.DataHdrLeth = PCMSize;

		byte[] h = header.getHeader();

		assert h.length == 44; // WAV鏍囧噯锛屽ご閮ㄥ簲璇ユ槸44瀛楄妭
		// write header
		fos.write(h, 0, h.length);
		// write data stream
		fis = new FileInputStream(src);
		size = fis.read(buf);
		while (size != -1) {
			fos.write(buf, 0, size);
			size = fis.read(buf);
		}
		fis.close();
		fos.close();
		System.out.println("Convert OK!");
	}
}
